package com.onelap.bls.tc2.ble;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.content.LocalBroadcastManager;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PermissionUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.blankj.utilcode.util.ServiceUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.onelap.bls.tc2.ui.index.DeviceBean;
import com.onelap.bls.tc2.ui.index.IndexActivity;
import com.onelap.bls.tc2.util.HandleUtils;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import static android.content.Context.BIND_AUTO_CREATE;
import static com.onelap.bls.tc2.ble.BleParams.StrUUID.RX_CHAR_UUID;
import static com.onelap.bls.tc2.ble.BleParams.StrUUID.RX_SERVICE_UUID;

public class BleUtil {

    public Context context = null;
    public BleUtil bleUtil = null;
    public BleCallback bleCallback = null;
    public BleService bleService = null;
    public BleServiceConnection bleServiceConnection = null;
    public BleBroadcastReceiver bleBroadcastReceiver = null;
    public BleLeScanCallback bleLeScanCallback = null;

    public BluetoothDevice bluetoothDevice = null;
    public BluetoothManager bluetoothManager = null;
    public BluetoothAdapter bluetoothAdapter = null;

    public BleParams.ScanDeviceStateCode scanDeviceStateCode = BleParams.ScanDeviceStateCode.START_SCAN;//设备搜索状态：未开始

    public BluetoothDevice getBluetoothDevice() {
        return bluetoothDevice;
    }

    public void setBluetoothDevice(BluetoothDevice bluetoothDevice) {
        this.bluetoothDevice = bluetoothDevice;
    }

    public BluetoothManager getBluetoothManager() {
        return bluetoothManager;
    }

    public void setBluetoothManager(BluetoothManager bluetoothManager) {
        this.bluetoothManager = bluetoothManager;
    }

    public BluetoothAdapter getBluetoothAdapter() {
        return bluetoothAdapter;
    }

    public void setBluetoothAdapter(BluetoothAdapter bluetoothAdapter) {
        this.bluetoothAdapter = bluetoothAdapter;
    }


    public BleUtil(Context context, BleCallback bleCallback) {
        this.bleUtil = this;
        this.context = context;
        this.bleCallback = bleCallback;
        this.bleServiceConnection = new BleServiceConnection(bleCallback, bleServiceConnectionCallback);
        this.bleBroadcastReceiver = new BleBroadcastReceiver(bleCallback);
        this.bleLeScanCallback = new BleLeScanCallback(bleCallback);
    }

    /**
     * 获取BleService
     *
     * @return BleService
     */
    public BleService getBleService() {
        return bleService;
    }

    /*    *//**
     * 连接蓝牙设备时使用  获取BleService
     *
     * @param bluetoothDevice bluetoothDevice
     * @return BleService
     *//*
    public BleService getBleService(BluetoothDevice bluetoothDevice) {
        //this.bluetoothDevice = bluetoothDevice;
        setBluetoothDevice(bluetoothDevice);
        return bleService;
    }*/


    /**
     * 蓝牙申请权限
     *
     * @param isDoIt 是否进行下一步操作
     */
    public void applyForPermission(final boolean isDoIt) {
        PermissionUtils.permission(BleParams.BlePermissionList).rationale(
                new PermissionUtils.OnRationaleListener() {
                    @Override
                    public void rationale(final ShouldRequest shouldRequest) {
                        BleDialogHelper.showRationaleDialog(shouldRequest);
                    }
                })
                .callback(new PermissionUtils.FullCallback() {
                    @Override
                    public void onGranted(List<String> permissionsGranted) {
                        bleCallback.bleHaveBlePermission(isDoIt);
                    }

                    @Override
                    public void onDenied(List<String> permissionsDeniedForever, List<String> permissionsDenied) {
                        if (!permissionsDeniedForever.isEmpty())
                            BleDialogHelper.showOpenAppSettingDialog();
                        else applyForPermission(isDoIt);
                    }
                })
                .theme(new PermissionUtils.ThemeCallback() {
                    @Override
                    public void onActivityCreate(Activity activity) {
                        ScreenUtils.setFullScreen(activity);
                    }
                })
                .request();
    }

    /**
     * 开始服务（暂不适用）
     */
    public void startBleService() {
        ServiceUtils.startService(BleService.class);
    }

    /**
     * 停止服务（暂不使用）
     */
    public void stopBleService() {
        ServiceUtils.stopService(BleService.class);
    }

    /**
     * 绑定蓝牙服务
     */
    public void bindBleService() {
        IntentFilter intentFilter = new IntentFilter();
        for (String s : BleParams.BleServiceIntentActions) {
            intentFilter.addAction(s);
        }
        ServiceUtils.bindService(BleService.class, bleServiceConnection, BIND_AUTO_CREATE);
        LocalBroadcastManager.getInstance(context).registerReceiver(bleBroadcastReceiver, intentFilter);
    }

    /**
     * 解绑蓝牙服务
     */
    public void unBindService() {
        if (ServiceUtils.isServiceRunning(BleService.class))
            ServiceUtils.unbindService(bleServiceConnection);
        LocalBroadcastManager.getInstance(context).unregisterReceiver(bleBroadcastReceiver);
    }

    /**
     * 检测蓝牙是否可用,可用的话则打开蓝牙
     */
    public void checkBluetoothIsAvailable() {
        if (!((Activity) context).getApplication().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            //设备不支持蓝牙
            bleCallback.bleBluetoothEnableState(false, false);
        } else {
            bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
            bluetoothAdapter = bluetoothManager != null ? bluetoothManager.getAdapter() : null;
            if (bluetoothAdapter == null)
                //设备不支持蓝牙
                bleCallback.bleBluetoothEnableState(false, false);
            else if (!bluetoothAdapter.isEnabled()) {
                //设备支持蓝牙，未打开蓝牙
                bleCallback.bleBluetoothEnableState(true, false);
                bluetoothAdapter.enable();
            } else
                //设备支持蓝牙，已打开蓝牙
                bleCallback.bleBluetoothEnableState(true, true);
        }
    }

    /**
     * 搜索蓝牙设备
     */
    public void bleScanDevice(boolean isScan) {
        if (bluetoothAdapter == null) {
            bleCallback.bleBluetoothEnableState(false, false);
            return;
        }
        if (!bluetoothAdapter.isEnabled()) {
            bleCallback.bleBluetoothEnableState(true, false);
            bluetoothAdapter.enable();
            return;
        }
        if (isScan) {
            bluetoothAdapter.startLeScan(bleLeScanCallback);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    bleScanDevice(false);
                    bleCallback.bleLeScanDevice(null, 0, null, BleParams.ScanDeviceStateCode.START_SCAN);
                }
            }, BleParams.Scan_Device_Time);
        } else {
            bluetoothAdapter.stopLeScan(bleLeScanCallback);
            bleCallback.bleLeScanDevice(null, 0, null, BleParams.ScanDeviceStateCode.START_SCAN);
        }
    }


    private Timer timer1 = new Timer();

    private TimerTask task1 = new TimerTask() {
        public void run() {
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    if (bleUtil.getBleService().getBluetoothGatt() != null)
                        showBattery(bleUtil.getBleService().getBluetoothGatt());
                }
            }, 100);
        }
    };

    public void disPlayCharacteristicsContent() {
        if (bleUtil.getBleService().getBluetoothGatt() != null)
            showVersion(bleUtil.getBleService().getBluetoothGatt());
        timer1.schedule(task1, 10, 5000);
    }

    private void showVersion(BluetoothGatt bluetoothGatt) {
        BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(BleParams.StrUUID.DEVICE_INFO_SERVICE_UUID));
        if (service == null) return;
        bluetoothGatt.readCharacteristic(service.getCharacteristic(UUID.fromString(BleParams.StrUUID.VERSION_NAME_UUID)));
    }

    private void showBattery(BluetoothGatt bluetoothGatt) {
        BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(BleParams.StrUUID.BATTERY_SERVICE_UUID));
        if (service == null) return;
        bluetoothGatt.readCharacteristic(service.getCharacteristic(UUID.fromString(BleParams.StrUUID.BATTERY_LEVEL_UUID)));
    }

    /**
     * 接收硬件通知
     *
     * @param bluetoothGatt bluetoothGatt
     */
    public void setCharacteristicNotification(BluetoothGatt bluetoothGatt) {
        if (bluetoothAdapter == null || bluetoothGatt == null) {
            LogUtils.i("", "BluetoothAdapter not initialized");
            return;
        }
        BluetoothGattService bluetoothGattService = bluetoothGatt.getService(UUID.fromString(RX_SERVICE_UUID));
        if (bluetoothGattService == null) {
            ToastUtils.showShort("BluetoothGattService Service == NULL");
            return;
        }
        BluetoothGattCharacteristic bluetoothGattCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(BleParams.StrUUID.TX_CHAR_UUID));
        if (bluetoothGattCharacteristic == null) {
            ToastUtils.showShort("BluetoothGattCharacteristic charateristic not found!");
            return;
        }
        bluetoothGatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
        BluetoothGattDescriptor descriptor = bluetoothGattCharacteristic.getDescriptor(UUID.fromString(BleParams.StrUUID.CCCD));
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        bluetoothGatt.writeDescriptor(descriptor);
    }

    public void writeRXCharacteristicUTF_8(String tempValue) throws UnsupportedEncodingException {
        BluetoothGatt bluetoothGatt = bleService.getBluetoothGatt();
        if (bluetoothGatt == null) {
            ToastUtils.showShort("设备未连接");
            return;
        }
        BluetoothGattService tempService = bluetoothGatt.getService(UUID.fromString("00001818-0000-1000-8000-00805F9B34FB"));
        if (tempService == null) {
            LogUtils.i("UUID Service == NULL");
            return;
        }
        BluetoothGattCharacteristic tempChar = tempService.getCharacteristic(UUID.fromString("A026E005-0A7D-4AB3-97FA-F1500F9FEB8B"));
        if (tempChar == null) {
            LogUtils.i("Rx charateristic not found!");
            return;
        }
        tempChar.setValue(tempValue.getBytes("UTF-8"));
        boolean status = bluetoothGatt.writeCharacteristic(tempChar);
        LogUtils.i("writeRXCharacteristicUTF_8", "write TXchar - status=" + status);
    }


    @SuppressWarnings("all")
    private BleServiceConnection.BleServiceConnectionCallback bleServiceConnectionCallback = new BleServiceConnection.BleServiceConnectionCallback() {
        @Override
        public void onBleServiceConnectionCallback(ComponentName componentName, IBinder iBinder) {
            bleService = ((BleService.LocalBinder) iBinder).getService(bleUtil);
        }
    };

/*    private MyHandler myHandler = new MyHandler(bleUtil);

    private static class MyHandler extends HandleUtils<BleUtil> {
        MyHandler(BleUtil rootT) {
            super(rootT);
        }

        @Override
        public void handler0Event(BleUtil object, Message msg) {
            super.handler0Event(object, msg);
            object.showBattery(object.getBleService().getBluetoothGatt());
        }
    }*/
}
